﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Data;
using StyleMVVM.DependencyInjection;
using StyleMVVM.UnitTests.TestClasses.ValidationObjects.Automobile;
using StyleMVVM.Validation;
using StyleMVVM.Validation.Impl;
using StyleMVVM.Validation.Impl.Fluent;
#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Windows.ApplicationModel.Resources;

#else
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endif

namespace StyleMVVM.UnitTests.Validation.Fluent
{
	[TestClass]
	public class IntPropertyModifierTests : BaseTestClass
	{
		[TestMethod]
		public void PlusOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.IntProperty(x => x.Wheels).Plus(4).GreaterThan.Value(4);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.Wheels = 1;

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void SubtractOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.IntProperty(x => x.Wheels).Minus(4).GreaterThan.Value(4);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car { Wheels = 8 };

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.Wheels = 9;

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void MultiplyOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.IntProperty(x => x.Wheels).Multiply(4).GreaterThan.Value(16);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car { Wheels = 0 };

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.Wheels = 5;

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void DivideOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.IntProperty(x => x.Wheels).Divide(4).GreaterThan.Value(4);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car { Wheels = 16 };

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.Wheels = 20;

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void ModOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.IntProperty(x => x.Wheels).Mod(4).GreaterThan.Value(2);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car { Wheels = 0 };

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.Wheels = 11;

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}
	}
}